using System;

namespace Client.Hotfix
{

    public abstract class BaseClient<Cmd, Msg>
    {

        protected int currentReconnectCount = 0;
        protected int maxReconnectCount = 3;
        protected bool IsInitiativeClose = false;
        protected MessageMap<Cmd, Msg> messageMap;
        public Func<byte[], byte[]> OnEncrypt { get; set; }
        public Func<byte[], byte[]> OnDecrypt { get; set; }
        public bool IsConnected { get; protected set; }
        public BaseClient()
        {
            messageMap = new();
        }

        public void Send(byte[] data)
        {
            if (data == null || data.Length == 0)
            {
                this.LogYellow("尝试发送空数据");
                return;
            }

            if (!IsConnected)
            {
                this.Warn("连接未建立，无法发送数据");
                return;
            }

            try
            {
                var processedData = OnEncrypt?.Invoke(data) ?? data;
                ActualSendToNetwork(processedData);
            }
            catch (Exception ex)
            {
                this.Error($"数据发送处理失败: {ex.Message}");
            }
        }

        public void OnReceiveData(byte[] data)
        {
            if (data == null || data.Length == 0)
            {
                this.LogYellow("接收到空数据");
                return;
            }

            try
            {
                byte[] processedData = OnDecrypt?.Invoke(data) ?? data;

                ActualReceiveFromNetwork(processedData);

            }
            catch (Exception ex)
            {
                this.Error($"数据接收处理失败: {ex.Message}");
            }
        }

        public void AddListener(Cmd key, Action<Msg> handle)
        {
            messageMap?.AddListener(key, handle);
        }

        public void RemoveListenerByClass(object target)
        {
            messageMap?.RemoveListenerByClass(target);
        }

        public void RemoveListenerByKey(Cmd key)
        {
            messageMap?.RemoveListenerByKey(key);
        }


        public void Dispose()
        {
            OnEncrypt = null;
            OnDecrypt = null;
        }
        public abstract void Connect(string address, int port);
        protected abstract void ActualSendToNetwork(byte[] data);
        protected abstract void ActualReceiveFromNetwork(byte[] data);
        public abstract void OnConnected(bool result);
        protected abstract void OnReconnect();
        public virtual void OnDisconnected()
        {
            IsConnected = false;
            if (!IsInitiativeClose)
            {
                OnReconnect();
            }
        }
        public virtual void Close()
        {
            IsConnected = false;
            IsInitiativeClose = true;
        }

    }
}